#ifndef TAGGED_PTR_H
#define TAGGED_PTR_H

#include <stdint.h>
#include <stdatomic.h>

// 标记指针结构
typedef struct {
    void* ptr;
    uintptr_t tag;
} tagged_ptr_t;

// 原子标记指针
typedef struct {
    atomic_uintptr_t raw;
} atomic_tagged_ptr_t;

// 初始化标记指针
static inline tagged_ptr_t make_tagged_ptr(void* ptr, uintptr_t tag) {
    tagged_ptr_t result = {ptr, tag};
    return result;
}

// 获取原始指针
static inline void* get_ptr(tagged_ptr_t tagged) {
    return tagged.ptr;
}

// 获取标记值
static inline uintptr_t get_tag(tagged_ptr_t tagged) {
    return tagged.tag;
}

// 原子操作函数
static inline tagged_ptr_t atomic_tagged_load(atomic_tagged_ptr_t* atomic, 
                                            memory_order order) {
    uintptr_t raw = atomic_load(&atomic->raw, order);
    tagged_ptr_t result = {
        (void*)(raw & ~(uintptr_t)1),  // 清除最低位获取指针
        raw & 1                         // 获取标记
    };
    return result;
}

static inline void atomic_tagged_store(atomic_tagged_ptr_t* atomic, 
                                     tagged_ptr_t value,
                                     memory_order order) {
    uintptr_t raw = (uintptr_t)value.ptr | value.tag;
    atomic_store(&atomic->raw, raw, order);
}

static inline bool atomic_tagged_compare_exchange_weak(
    atomic_tagged_ptr_t* atomic,
    tagged_ptr_t* expected,
    tagged_ptr_t desired,
    memory_order success,
    memory_order failure) {
    
    uintptr_t exp_raw = (uintptr_t)expected->ptr | expected->tag;
    uintptr_t des_raw = (uintptr_t)desired.ptr | desired.tag;
    
    bool success_flag = atomic_compare_exchange_weak(
        &atomic->raw,
        &exp_raw,
        des_raw,
        success,
        failure
    );
    
    if (!success_flag) {
        expected->ptr = (void*)(exp_raw & ~(uintptr_t)1);
        expected->tag = exp_raw & 1;
    }
    
    return success_flag;
}

#endif // TAGGED_PTR_H 